package cn.lili.xiaoran;

import cn.hutool.cache.CacheUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.config.RequestConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class BaseUtil {
	// 配置信息
	public static final RequestConfig requestConfig = RequestConfig.custom()
			// 设置连接超时时间(单位毫秒)
			.setConnectTimeout(4000)
			// 设置请求超时时间(单位毫秒)
			.setConnectionRequestTimeout(4000)
			// socket读写超时时间(单位毫秒)
			.setSocketTimeout(4000)
			// 设置是否允许重定向(默认为true)
			.setRedirectsEnabled(true).build();
	// 圆周率
	public static final double PI = 3.14159265358979324;
	// 赤道半径(单位m)
	private static final double EARTH_RADIUS = 6378.137;

	



	private final static String UNDERLINE = "_";

	@Lazy
	@Autowired
    CacheUtil cacheUtil;

	@Lazy
	@Autowired
	private RedisTemplate redisTemplate;

	private static RedisTemplate staticredisTemplate;

	private static CacheUtil staticCacheUtil;

	public static Object map2Object(Map<String, Object> map, Class<?> clazz) throws Exception {
		if (map == null) {
			return null;
		} else {
			Object obj = null;

			try {
				obj = clazz.newInstance();
				Field[] fields = obj.getClass().getDeclaredFields();
				Field[] var4 = fields;
				int var5 = fields.length;

				for (int var6 = 0; var6 < var5; ++var6) {
					Field field = var4[var6];
					int mod = field.getModifiers();
					if (!Modifier.isStatic(mod) && !Modifier.isFinal(mod)) {
						field.setAccessible(true);
						if (field.getType().toString().contains("Integer") && map.get(field.getName()) != null) {
							field.set(obj, Integer.parseInt(map.get(field.getName()).toString()));
						} else if (field.getType().toString().contains("String") && map.get(field.getName()) != null) {
							field.set(obj,
									map.get(field.getName()) == null ? null : map.get(field.getName()).toString());
						} else if (field.getType().toString().contains("Long") && map.get(field.getName()) != null) {
							field.set(obj,
									map.get(field.getName()) == null ? null : Long.parseLong(map.get(field.getName())+""));
						} else if (field.getType().toString().contains("Short") && map.get(field.getName()) != null) {
							field.set(obj,
									map.get(field.getName()) == null ? null : Short.valueOf(map.get(field.getName()).toString()));
						} else {
							field.set(obj, map.get(field.getName()));
						}
					}
				}
			} catch (Exception var9) {
				var9.printStackTrace();
			}

			return obj;
		}
	}

	/**
	 * 将Map转为Bean
	 *
	 * @return
	 * @throws IntrospectionException    获取类属性异常
	 * @throws IllegalAccessException    创建Bean对象异常
	 * @throws InstantiationException    创建Bean对象异常
	 * @throws InvocationTargetException 对象转换异常
	 */
	public static Object maptoBean(Object obj, Map map) {
		try {
			// 1.获取bean信息
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor prop : properties) {
				String key = prop.getName();
				if (map.containsKey(key) && map.get(key) != null) {
					Object value = map.get(key);
					Method setMethod = prop.getWriteMethod();
					if (setMethod != null) {
						setMethod.invoke(obj, value);
					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}

	static public String GetFiledValue(String key, String filed, Map<String, String> data) {

		String value = "";
		String field = key + "[" + filed + "]";
		if (data.containsKey(field)) {
			value = data.get(field);
		}

		return value;
	}

	static public <T> Map<String, String> GetBeanMap(String key, Class<T> clazz, Map<String, String> data) {

		Map<String, String> bean = new HashMap<String, String>();
		List<Field> fields = new ArrayList<Field>();
		fields.addAll(Arrays.asList(clazz.getDeclaredFields()));

		Class<?> superClazz = clazz.getSuperclass();
		while (!(superClazz.getName().equals(Object.class.getName()))) {
			fields.addAll(Arrays.asList(superClazz.getDeclaredFields()));
			superClazz = superClazz.getSuperclass();
		}

		for (Field f : fields) {
			String modifier = Modifier.toString(f.getModifiers());
			if (modifier.indexOf("final") > -1 || modifier.indexOf("static") > -1) {
				continue;
			} else {
				String field = key + "[" + f.getName() + "]";
				if (data.containsKey(field)) {
					bean.put(f.getName(), data.get(field));
				}
			}
		}
		return bean;
	}

	static public <T> Map<String, String> FilterBeanMap(Map<String, String> data) {

		Map<String, String> bean = new HashMap<String, String>();

		for (String key : data.keySet()) {
			if (!key.contains("[")) {
				bean.put(key, data.get(key));
			}
		}

		return bean;
	}

	static public Long GetLongValue(String key, Map<String, Object> data) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			if (object instanceof Long) {
				return (Long) object;
			}
			return Long.parseLong(object.toString());
		} else {
			return null;
		}
	}

	static public Long GetLongValue(String key, Map<String, Object> data, long defaultValue) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			if (object == null) {
				return defaultValue;
			} else {
				return Long.parseLong(object.toString());
			}

		} else {
			return defaultValue;
		}
	}

	static public int GetIntValue(String key, Map<String, Object> data) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			return Integer.parseInt(object.toString());
		} else {
			return 0;
		}
	}

	static public BigDecimal GetBigDecimalValue(String key, Map<String, Object> data) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			if (object == null) {
				return new BigDecimal(0);
			} else if (object instanceof BigDecimal) {
				return (BigDecimal) object;
			} else if (object instanceof String) {
				return new BigDecimal((String) object);
			} else if (object instanceof BigInteger) {
				return new BigDecimal((BigInteger) object);
			} else if (object instanceof Number) {
				return new BigDecimal(((Number) object).doubleValue());
			} else {
				throw new ClassCastException("Can Not make [" + object + "] into a BigDecimal.");
			}
		} else {
			return new BigDecimal(0);
		}
	}

	static public int GetIntValue(String key, Map<String, Object> data, int defaultValue) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			return Integer.parseInt(object.toString());
		} else {
			return defaultValue;
		}
	}

	static public double GetDoubleValue(String key, Map<String, Object> data) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			return Double.parseDouble(object.toString());
		} else {
			return 0;
		}
	}

	static public boolean GetBoolValue(String key, Map<String, Object> data) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			return Boolean.parseBoolean(object.toString());
		} else {
			return false;
		}
	}

	static public String GetStringValue(String key, Map<String, Object> data) {
		if (data.containsKey(key) && data.get(key) != null) {
			Object object = data.get(key);
			return object.toString();
		} else {
			return "";
		}
	}

	static public String GetStringValue(String str) {
		if (StringUtils.isBlank(str)) {
			return "";
		} else {
			return str;
		}
	}

	@SuppressWarnings("unchecked")
	static public Map<String, Object> GetMapValue(String key, Map<String, Object> data) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			if (object instanceof Map) {
				return (Map<String, Object>) object;
			}
		}

		return new HashMap<String, Object>();

	}

	@SuppressWarnings("unchecked")
	static public List<Map<String, Object>> GetListValue(String key, Map<String, Object> data) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			if (object instanceof JSONArray) {
				return (List<Map<String, Object>>) object;
			}
			if (object instanceof List) {
				return (List<Map<String, Object>>) object;
			}
		}

		return new ArrayList<Map<String, Object>>();

	}

	@SuppressWarnings("unchecked")
	static public <T> List<T> GetListStringValue(String key, Map<String, Object> data) {
		if (data.containsKey(key)) {
			Object object = data.get(key);
			if (object instanceof List) {
				return (List<T>) object;
			}
		}
		return new ArrayList<T>();

	}

	static public long GetTime(String time) {

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
		simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));

		try {
			return simpleDateFormat.parse(time).getTime();

		} catch (ParseException e) {
			e.printStackTrace();
			return 0;
		}

	}

	static public long GetDayDate(String date) {

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));

		try {
			return simpleDateFormat.parse(date).getTime();

		} catch (ParseException e) {
			e.printStackTrace();
			return 0;
		}

	}

	static public Set<String> ConvertListToSet(List<Map<String, Object>> list, String key) {
		Set<String> set = new HashSet<String>();
		for (Map<String, Object> map : list) {
			if (map.containsKey(key)) {
				set.add(map.get(key).toString());
			}
		}
		return set;
	}

	static public <T> Map<String, T> ConvertListToMapByKey(Class<T> clazz, List<T> list, String key) {
		Map<String, T> map = new HashMap<String, T>();
		Field field = null;
		try {
			field = clazz.getDeclaredField(key);
			field.setAccessible(true);
			if (field != null) {
				for (T t : list) {
					map.put(field.get(t).toString(), t);
				}
			}
		} catch (Exception e) {
			map = new HashMap<String, T>();
		}

		return map;
	}

	static public <T> Map<String, String> ConvertListToMapByKey(Class<T> clazz, List<T> list, String key,
			String value) {
		Map<String, String> map = new HashMap<String, String>();
		Field fieldKey = null;
		Field fieldValue = null;
		try {
			fieldKey = clazz.getDeclaredField(key);
			fieldKey.setAccessible(true);
			fieldValue = clazz.getDeclaredField(value);
			fieldValue.setAccessible(true);
			if (fieldKey != null) {
				for (T t : list) {
					map.put(fieldKey.get(t).toString(), fieldValue.get(t).toString());
				}
			}
		} catch (Exception e) {
			map = new HashMap<String, String>();
		}

		return map;
	}

	/**
	 * 保留两位小数
	 * 
	 * @param d
	 * @return
	 */
	public static double formatDouble(double d) {
		double result = Math.round(d * 100) / 100d;
		return result;
	}

	static public <T> Map<String, Object> GetUnchangedValue(List<String> keys, Class<T> clazz, T t) {
		Map<String, Object> unChanged = new HashMap<String, Object>();
		for (String key : keys) {
			Field field = null;
			try {
				field = clazz.getDeclaredField(key);
				if (field != null) {
					field.setAccessible(true);
					unChanged.put(key, field.get(t));
				}
			} catch (Exception e) {
			}
		}
		return unChanged;
	}

	static public List<String> GetListValuesByLength(String... params) {
		List<String> list = new ArrayList<String>();
		for (String string : params) {
			list.add(string);
		}
		return list;
	}

	static public Map<String, Object> ConvertMap(BeanMap beanMap) {
		Map<String, Object> map = new HashMap<String, Object>();
		for (Object o : beanMap.entrySet()) {
			@SuppressWarnings("unchecked")
			Map.Entry<String, Object> entry = (Map.Entry<String, Object>) o;
			String key = entry.getKey();
			Object value = entry.getValue();
			map.put(key, value);
		}
		return map;
	}

	/**
	 * 调用本地的服务
	 *
	 */
	public static String CallLocalService(String url, String param) {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			conn.setRequestProperty("Content-Type", "application/json");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常！" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}

	public static String getPassword(int n) {
//		char[] pw = new char[n];
//		int c = 'A';
//		int r1 = 0;
//		for (int i = 0; i < n; i++) {
//			r1 = (int) (Math.random() * 3);
//			switch (r1) {
//			case 0:
//				c = '0' + (int) (Math.random() * 10);
//				break;
//			case 1:
//				c = 'a' + (int) (Math.random() * 26);
//				break;
//			case 2:
//				c = 'A' + (int) (Math.random() * 26);
//				break;
//			}
//			pw[i] = (char) c;
//		}
//		return new String(pw).replace('0', 'A').toUpperCase(); // make it uppercase to make it easier for the user
		StringBuilder str = new StringBuilder();// 定义变长字符串
		Random random = new Random();
		// 随机生成数字，并添加到字符串
		for (int i = 0; i < n; i++) {
			str.append(random.nextInt(10));
		}
		// 将字符串转换为数字并输出
//		int num=Integer.parseInt();
		return str.toString();
	}

	/**
	 * 比较两个list 并返回不同元素
	 * 
	 * @param preList
	 * @param curList
	 * @return 两个List<Map<String,Object>> 的不同元素
	 */
	public static List<Map<String, Object>> GetDifferent(List<Map<String, Object>> preList,
			List<Map<String, Object>> curList) {
		List<Map<String, Object>> diff = new ArrayList<Map<String, Object>>();

		Map<Map<String, Object>, Integer> map = new HashMap<Map<String, Object>, Integer>(curList.size());
		for (Map<String, Object> subCur : curList) {
			map.put(subCur, 1);
		}

		for (Map<String, Object> subPre : preList) {
			if (map.get(subPre) != null) {
				map.put(subPre, 2);
				continue;
			}
			diff.add(subPre);
		}

		for (Map.Entry<Map<String, Object>, Integer> entry : map.entrySet()) {
			if (entry.getValue() == 1) {
				diff.add(entry.getKey());
			}
		}
		return diff;
	}

	public static boolean isBearer(String card) {
		Pattern p = Pattern.compile("^(RC-CCM|L-FCM|G-CCM|L-IM|N-CCM)\\d\\d\\d\\d$");
		Matcher m = p.matcher(card);
		return m.matches();
	}

	/**
	 * 获取本机的外网ip地址
	 * 
	 * @return
	 */
	public static String getV4IP() {
		String ip = "";
		String chinaz = "http://ip.chinaz.com";

		StringBuilder inputLine = new StringBuilder();
		String read = "";
		URL url = null;
		HttpURLConnection urlConnection = null;
		BufferedReader in = null;
		try {
			url = new URL(chinaz);
			urlConnection = (HttpURLConnection) url.openConnection();
			in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
			while ((read = in.readLine()) != null) {
				inputLine.append(read + "\r\n");
			}
			// System.out.println(inputLine.toString());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		Pattern p = Pattern.compile("\\<dd class\\=\"fz24\">(.*?)\\<\\/dd>");
		Matcher m = p.matcher(inputLine.toString());
		if (m.find()) {
			String ipstr = m.group(1);
			ip = ipstr;
			// System.out.println(ipstr);
		}
		return ip;
	}

	/**
	 * 判断时间是否在时间段内
	 * 
	 * @param nowTime
	 * @param beginTime
	 * @param endTime
	 * @return
	 */
	public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
		Calendar date = Calendar.getInstance();
		date.setTime(nowTime);

		Calendar begin = Calendar.getInstance();
		begin.setTime(beginTime);

		Calendar end = Calendar.getInstance();
		end.setTime(endTime);

		if (nowTime.getTime() > beginTime.getTime() && nowTime.getTime() <= endTime.getTime()) {
			return true;
		} else {
			return false;
		}
	}

	// 获取本周的开始时间
	public static Date getBeginDayOfWeek() {
		Date date = new Date();
		if (date == null) {
			return null;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayofweek == 1) {
			dayofweek += 7;
		}
		cal.add(Calendar.DATE, 2 - dayofweek);
		return getDayStartTime(cal.getTime());
	}

	// 获取本周的结束时间
	public static Date getEndDayOfWeek() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getBeginDayOfWeek());
		cal.add(Calendar.DAY_OF_WEEK, 6);
		Date weekEndSta = cal.getTime();
		return getDayEndTime(weekEndSta);
	}

	// 获取本月的开始时间
	public static Date getBeginDayOfMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(getNowYear(), getNowMonth() - 1, 1);
		return getDayStartTime(calendar.getTime());
	}

	// 获取本月的结束时间
	public static Date getEndDayOfMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(getNowYear(), getNowMonth() - 1, 1);
		int day = calendar.getActualMaximum(5);
		calendar.set(getNowYear(), getNowMonth() - 1, day);
		return getDayEndTime(calendar.getTime());
	}

	// 获取本年的开始时间
	public static Date getBeginDayOfYear() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, getNowYear());
		cal.set(Calendar.MONTH, Calendar.JANUARY);
		cal.set(Calendar.DATE, 1);
		return getDayStartTime(cal.getTime());
	}

	// 获取本年的结束时间
	public static Date getEndDayOfYear() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, getNowYear());
		cal.set(Calendar.MONTH, Calendar.DECEMBER);
		cal.set(Calendar.DATE, 31);
		return getDayEndTime(cal.getTime());
	}

	// 获取某个日期的开始时间
	public static Timestamp getDayStartTime(Date d) {
		Calendar calendar = Calendar.getInstance();
		if (null != d) {
			calendar.setTime(d);
		}
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0,
				0, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Timestamp(calendar.getTimeInMillis());
	}

	// 获取某个日期的结束时间
	public static Timestamp getDayEndTime(Date d) {
		Calendar calendar = Calendar.getInstance();
		if (null != d) {
			calendar.setTime(d);
		}
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23,
				59, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return new Timestamp(calendar.getTimeInMillis());
	}

	// 获取今年是哪一年
	public static Integer getNowYear() {
		Date date = new Date();
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		return Integer.valueOf(gc.get(1));
	}

	// 获取本月是哪一月
	public static int getNowMonth() {
		Date date = new Date();
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		return gc.get(2) + 1;
	}

	// 两个日期相减得到的天数
	public static int getDiffDays(Date beginDate, Date endDate) {
		if (beginDate == null || endDate == null) {
			throw new IllegalArgumentException("getDiffDays param is null!");
		}
		long diff = (endDate.getTime() - beginDate.getTime()) / (1000 * 60 * 60 * 24);
		int days = new Long(diff).intValue();
		return days;
	}

	// 两个日期相减得到的毫秒数
	public static long dateDiff(Date beginDate, Date endDate) {
		long date1ms = beginDate.getTime();
		long date2ms = endDate.getTime();
		return date2ms - date1ms;
	}

	// 获取两个日期中的最大日期
	public static Date max(Date beginDate, Date endDate) {
		if (beginDate == null) {
			return endDate;
		}
		if (endDate == null) {
			return beginDate;
		}
		if (beginDate.after(endDate)) {
			return beginDate;
		}
		return endDate;
	}

	// 获取两个日期中的最小日期
	public static Date min(Date beginDate, Date endDate) {
		if (beginDate == null) {
			return endDate;
		}
		if (endDate == null) {
			return beginDate;
		}
		if (beginDate.after(endDate)) {
			return endDate;
		}
		return beginDate;
	}

	// 返回某月该季度的第一个月
	public static Date getFirstSeasonDate(Date date) {
		final int[] SEASON = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4 };
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int sean = SEASON[cal.get(Calendar.MONTH)];
		cal.set(Calendar.MONTH, sean * 3 - 3);
		return cal.getTime();
	}

	// 返回某个日期下几天的日期
	public static Date getNextDay(Date date, int i) {
		Calendar cal = new GregorianCalendar();
		cal.setTime(date);
		cal.set(Calendar.DATE, cal.get(Calendar.DATE) + i);
		return cal.getTime();
	}

	// 返回某个日期前几天的日期
	public static Date getFrontDay(Date date, int i) {
		Calendar cal = new GregorianCalendar();
		cal.setTime(date);
		cal.set(Calendar.DATE, cal.get(Calendar.DATE) - i);
		return cal.getTime();
	}

	private final static SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
	private final static SimpleDateFormat longHourSdf = new SimpleDateFormat("yyyy-MM-dd HH");
	private final static SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	/**
	 * 当前季度的开始时间
	 *
	 * @return
	 */
	public static Date getCurrentQuarterStartTime() {
		Calendar c = Calendar.getInstance();
		int currentMonth = c.get(Calendar.MONTH) + 1;
		Date now = null;
		try {
			if (currentMonth >= 1 && currentMonth <= 3)
				c.set(Calendar.MONTH, 0);
			else if (currentMonth >= 4 && currentMonth <= 6)
				c.set(Calendar.MONTH, 3);
			else if (currentMonth >= 7 && currentMonth <= 9)
				c.set(Calendar.MONTH, 4);
			else if (currentMonth >= 10 && currentMonth <= 12)
				c.set(Calendar.MONTH, 9);
			c.set(Calendar.DATE, 1);
			now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return now;
	}

	/**
	 * 当前季度的结束时间
	 *
	 * @return
	 */
	public static Date getCurrentQuarterEndTime() {
		Calendar c = Calendar.getInstance();
		int currentMonth = c.get(Calendar.MONTH) + 1;
		Date now = null;
		try {
			if (currentMonth >= 1 && currentMonth <= 3) {
				c.set(Calendar.MONTH, 2);
				c.set(Calendar.DATE, 31);
			} else if (currentMonth >= 4 && currentMonth <= 6) {
				c.set(Calendar.MONTH, 5);
				c.set(Calendar.DATE, 30);
			} else if (currentMonth >= 7 && currentMonth <= 9) {
				c.set(Calendar.MONTH, 8);
				c.set(Calendar.DATE, 30);
			} else if (currentMonth >= 10 && currentMonth <= 12) {
				c.set(Calendar.MONTH, 11);
				c.set(Calendar.DATE, 31);
			}
			now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return now;
	}

	// 获取某年某月到某年某月按天的切片日期集合（间隔天数的日期集合）
	public static List getTimeList(int beginYear, int beginMonth, int endYear, int endMonth, int k) {
		List list = new ArrayList();
		if (beginYear == endYear) {
			for (int j = beginMonth; j <= endMonth; j++) {
				list.add(getTimeList(beginYear, j, k));
			}
		} else {
			for (int j = beginMonth; j < 12; j++) {
				list.add(getTimeList(beginYear, j, k));
			}
			for (int i = beginYear + 1; i < endYear; i++) {
				for (int j = 0; j < 12; j++) {
					list.add(getTimeList(i, j, k));
				}
			}
			for (int j = 0; j <= endMonth; j++) {
				list.add(getTimeList(endYear, j, k));
			}
		}
		return list;
	}

	// 获取某年某月按天切片日期集合（某个月间隔多少天的日期集合）
	public static List getTimeList(int beginYear, int beginMonth, int k) {
		List list = new ArrayList();
		Calendar begincal = new GregorianCalendar(beginYear, beginMonth, 1);
		int max = begincal.getActualMaximum(Calendar.DATE);
		for (int i = 1; i < max; i = i + k) {
			list.add(begincal.getTime());
			begincal.add(Calendar.DATE, k);
		}
		begincal = new GregorianCalendar(beginYear, beginMonth, max);
		list.add(begincal.getTime());
		return list;
	}

	// 获取某年某月的第一天日期
	public static Date getStartMonthDate(int year, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, 1);
		return calendar.getTime();
	}

	// 获取某年某月的最后一天日期
	public static Date getEndMonthDate(int year, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, 1);
		int day = calendar.getActualMaximum(5);
		calendar.set(year, month - 1, day);
		return calendar.getTime();
	}

	public static List<?> getArrayList(List<Object> list, int num) {

		for (int i = 0; i < num; i++) {
			list.add("");
		}
		return list;
	}

	/**
	 * 抽奖方法 create time: 2019/7/5 23:08
	 * 
	 * @param orignalRates 商品中奖概率列表，保证顺序和实际物品对应
	 * @return 中奖商品索引
	 */
	public static int lottery(List<Double> orignalRates, double sumRate) {

		if (orignalRates == null || orignalRates.isEmpty()) {
			return -1;
		}

		int size = orignalRates.size();
		// 计算总概率，这样可以保证不一定总概率是1
//		double sumRate = 0d;
		if (sumRate == 0) {
			for (double rate : orignalRates) {
				sumRate += rate;
			}

		}

		// 计算每个物品在总概率的基础下的概率情况
		List<Double> sortOrignalRates = new ArrayList<>(size);
		Double tempSumRate = 0d;
		for (double rate : orignalRates) {
			tempSumRate += rate;
			sortOrignalRates.add(tempSumRate / sumRate);
		}

		// 根据区块值来获取抽取到的物品索引
		double nextDouble = Math.random();
		sortOrignalRates.add(nextDouble);
		Collections.sort(sortOrignalRates);
		return sortOrignalRates.indexOf(nextDouble);
	}

	// 上传到微信素材库
	public static JSONObject uploadFileWX(String URL, File file, String type, String accessToken) throws Exception {
//        File file = new File(filePath);
		if (!file.exists() || !file.isFile()) {
			throw new IOException("文件不存在！");
		}

		String url = URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type);
		URL urlObj = new URL(url);

		// 创建Http连接
		HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
		conn.setRequestMethod("POST");
		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setUseCaches(false); // 使用post提交需要设置忽略缓存

		// 消息请求头信息
		conn.setRequestProperty("Connection", "Keep-Alive");
		conn.setRequestProperty("Charset", "UTF-8");

		// 设置边界
		String BOUNDARY = "----------" + System.currentTimeMillis();
		conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);

		StringBuilder sb = new StringBuilder();
		sb.append("--"); // 必须多两道线
		sb.append(BOUNDARY);
		sb.append("\r\n");
		sb.append("Content-Disposition:form-data;name=\"media\";filename=\"" + file.getName() + "\";filelength=\""
				+ file.length() + "\"\r\n");
		sb.append("Content-Type:application/octet-stream\r\n\r\n");

		byte[] head = sb.toString().getBytes("utf-8");

		// 创建输出流
		OutputStream out = new DataOutputStream(conn.getOutputStream());
		// 获得输出流表头
		out.write(head);

		// 文件正文部分
		DataInputStream in = new DataInputStream(new FileInputStream(file));
		int bytes = 0;
		byte[] bufferOut = new byte[1024 * 1024 * 10]; // 10M
		while ((bytes = in.read(bufferOut)) != -1) {
			out.write(bufferOut, 0, bytes);
		}
		in.close();

		// 结尾
		byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");
		out.write(foot);
		out.flush();
		out.close();

		// 获取响应
		StringBuffer buffer = new StringBuffer();
		BufferedReader reader = null;
		String result = null;
		try {
			reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line = null;
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			if (result == null) {
				result = buffer.toString();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			reader.close();
		}
		System.out.println(result);
//        String mediaId = "";
//        if (!type.equals("image")) {
//        	mediaId = JSONObject.fromObject(result).getString(type + "_media_id");
//        } else {
//        	mediaId = JSONObject.fromObject(result).getString("media_id");
//        }
		return JSONObject.parseObject(result);
	}

	public static byte[] string2Bytes(String str) {

		if (str == null || str.equals("")) {
			return null;
		}

		str = str.toUpperCase();
		int length = str.length() / 2;
		char[] strChar = str.toCharArray();
		byte[] bt = new byte[length];

		for (int i = 0; i < length; i++) {
			int index = i * 2;
			bt[i] = (byte) (char2Byte(strChar[index]) << 4 | char2Byte(strChar[index + 1]));
		}

		return bt;
	}

	private static byte char2Byte(char ch) {
		return (byte) "0123456789ABCDEF".indexOf(ch);
	}

	public final static long getLong(byte[] bt, boolean isAsc) {
		// BIG_ENDIAN
		if (bt == null) {
			throw new IllegalArgumentException("byte array is null.");
		}
		if (bt.length > 8) {
			throw new IllegalArgumentException("byte array size more than 8.");
		}
		long result = 0;
		if (isAsc)
			for (int i = bt.length - 1; i >= 0; i--) {
				result <<= 8;
				result |= (bt[i] & 0x00000000000000ff);
			}
		else
			for (int i = 0; i < bt.length; i++) {
				result <<= 8;
				result |= (bt[i] & 0x00000000000000ff);
			}
		return result;
	}




	/**
	 * 字符串转换为16进制字符串
	 * 
	 * @param s
	 * @return
	 */
	public static String stringToHexString(String s) {
		String str = "";
		for (int i = 0; i < s.length(); i++) {
			int ch = s.charAt(i);
			String s4 = Integer.toHexString(ch);
			str = str + s4;
		}
		return str;
	}

	/**
	 * 16进制字符串转换为字符串
	 * 
	 * @param s
	 * @return
	 */
	public static String hexStringToString(String s) {
		if (s == null || s.equals("")) {
			return null;
		}
		s = s.replace(" ", "");
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			s = new String(baKeyword, "gbk");
			new String();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return s;
	}

	public static String getCheckCode(int length) {
		String ZiMu = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGJKLZXCVBNM1234567890";
		String result = "";
		Random random = new Random();
		for (int i = 0; i < length; i++) {
			int index = random.nextInt(ZiMu.length());
			char c = ZiMu.charAt(index);
			result += c;
		}
		return result;

	}

	/***
	 * 下划线命名转为驼峰命名
	 *
	 * @param para 下划线命名的字符串
	 */

	public static String underlineToHump(String para) {
		StringBuilder result = new StringBuilder();
		String a[] = para.split(UNDERLINE);
		for (String s : a) {
			if (!para.contains(UNDERLINE)) {
				result.append(s);
				continue;
			}
			if (result.length() == 0) {
				result.append(s.toLowerCase());
			} else {
				result.append(s.substring(0, 1).toUpperCase());
				result.append(s.substring(1).toLowerCase());
			}
		}
		return result.toString();
	}

	/***
	 * 驼峰命名转为下划线命名
	 *
	 * @param para 驼峰命名的字符串
	 */

	public static String humpToUnderline(String para) {
		StringBuilder sb = new StringBuilder(para);
		int temp = 0;// 定位
		if (!para.contains(UNDERLINE)) {
			for (int i = 0; i < para.length(); i++) {
				if (Character.isUpperCase(para.charAt(i))) {
					sb.insert(i + temp, UNDERLINE);
					temp += 1;
				}
			}
		}
		return sb.toString().toUpperCase();
	}

}
